{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([[ 1.      ,  0.044136, -0.537706],\n",
       "        [ 1.      ,  0.131337, -0.339109],\n",
       "        [ 1.      ,  0.148654, -0.328513],\n",
       "        [ 1.      ,  0.094491, -0.240963],\n",
       "        [ 1.      ,  0.14864 , -0.22733 ]]),\n",
       " (150, 3))"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "\n",
    "#加载数据\n",
    "def load_data(file_name):\n",
    "    with open(file_name) as fr:\n",
    "        lines = fr.readlines()\n",
    "\n",
    "    data = np.empty((len(lines), 3), dtype=float)\n",
    "\n",
    "    for i in range(len(lines)):\n",
    "        line = lines[i].split('\\t')\n",
    "        data[i] = line\n",
    "\n",
    "    #根据y排序,主要是为了画图\n",
    "    argsort = data.argsort(axis=0)[:, 2]\n",
    "    data = data[argsort]\n",
    "\n",
    "    return data\n",
    "\n",
    "\n",
    "data = load_data('简单数据_训练.txt')\n",
    "data[:5], data.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "#定义常量\n",
    "N, M = data.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from matplotlib import pyplot as plt\n",
    "\n",
    "\n",
    "#画图\n",
    "def draw(pred=None):\n",
    "    plt.scatter(data[:, 1], data[:, -1])\n",
    "\n",
    "    if pred is not None:\n",
    "        plt.scatter(data[:, 1], pred)\n",
    "\n",
    "\n",
    "draw()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Node col=0,value=1.00\n",
      "Leaf value=1.00\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#创建节点和叶子对象,用来构建树\n",
    "class Node():\n",
    "    def __init__(self, col, value):\n",
    "        self.col = col\n",
    "        self.value = value\n",
    "        self.lt_node = None\n",
    "        self.gt_node = None\n",
    "\n",
    "    def __call__(self, data):\n",
    "        if data[self.col] > self.value:\n",
    "            return self.gt_node(data)\n",
    "        return self.lt_node(data)\n",
    "\n",
    "    def __str__(self):\n",
    "        return 'Node col=%d,value=%.2f' % (self.col, self.value)\n",
    "\n",
    "\n",
    "class Leaf():\n",
    "    def __init__(self, value):\n",
    "        self.value = value\n",
    "\n",
    "    def __call__(self, data):\n",
    "        return self.value\n",
    "\n",
    "    def __str__(self):\n",
    "        return 'Leaf value=%.2f' % self.value\n",
    "\n",
    "\n",
    "node = Node(0, 1)\n",
    "leaf = Leaf(1)\n",
    "print(node)\n",
    "print(leaf)\n",
    "\n",
    "node.lt_node = leaf\n",
    "node(np.array([0, 0]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "317.45354816255235"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#衡量一个数据子集y的一致性\n",
    "def get_error(data):\n",
    "    return np.var(data[:, -1]) * len(data)\n",
    "\n",
    "\n",
    "get_error(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((116, 3), (34, 3))"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#切分数据\n",
    "def split_data(data, col, value):\n",
    "    data_gt = data[data[:, col] > value]\n",
    "    data_lt = data[data[:, col] <= value]\n",
    "\n",
    "    return data_gt, data_lt\n",
    "\n",
    "\n",
    "data_gt, data_lt = split_data(data, 1, 0.2)\n",
    "data_gt.shape, data_lt.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(80.42881008701248, 1, 0.39435)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def get_split_col_value(data):\n",
    "    min_error = np.inf\n",
    "    min_col = 0\n",
    "    min_value = 0\n",
    "\n",
    "    #遍历所有列\n",
    "    for col in range(M - 1):\n",
    "\n",
    "        #遍历所有值\n",
    "        for value in np.unique(data[:, col]):\n",
    "\n",
    "            #切分数据\n",
    "            data_gt, data_lt = split_data(data, col, value)\n",
    "\n",
    "            #如果一个子集是空,则说明另一个一定是全集,这种切分是没有意义的\n",
    "            if len(data_gt) == 0 or len(data_lt) == 0:\n",
    "                continue\n",
    "\n",
    "            #计算切分后的loss是否下降了\n",
    "            error = get_error(data_gt) + get_error(data_lt)\n",
    "            if error < min_error:\n",
    "                min_col = col\n",
    "                min_value = value\n",
    "                min_error = error\n",
    "\n",
    "    return min_error, min_col, min_value\n",
    "\n",
    "\n",
    "get_split_col_value(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<__main__.Node at 0x7f66480ca128>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def get_node(data):\n",
    "\n",
    "    min_error, min_col, min_value = get_split_col_value(data)\n",
    "\n",
    "    #前剪枝\n",
    "    #切分之后loss下降要超过1才切分,这是为了避免过拟合,否则定义为叶子节点\n",
    "    #这里故意训练一个复杂的树,方便后面后剪枝\n",
    "    if get_error(data) - min_error < 1:\n",
    "        return Leaf(data[:, -1].mean())\n",
    "\n",
    "    #创建新的节点\n",
    "    node = Node(min_col, min_value)\n",
    "\n",
    "    #切分数据\n",
    "    data_gt, data_lt = split_data(data, node.col, node.value)\n",
    "\n",
    "    #前剪枝\n",
    "    #切分后的子集不能太小,这是为了避免过拟合\n",
    "    if len(data_gt) < 3 or len(data_lt) < 3:\n",
    "        return Leaf(data[:, -1].mean())\n",
    "\n",
    "    #左右节点继续递归\n",
    "    node.gt_node = get_node(data_gt)\n",
    "    node.lt_node = get_node(data_lt)\n",
    "\n",
    "    return node\n",
    "\n",
    "\n",
    "root = get_node(data)\n",
    "root"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "---- Node col=1,value=0.39\n",
      "-------- Node col=1,value=0.58\n",
      "------------ Node col=1,value=0.80\n",
      "---------------- Leaf value=3.97\n",
      "---------------- Leaf value=3.01\n",
      "------------ Leaf value=1.98\n",
      "-------- Node col=1,value=0.20\n",
      "------------ Leaf value=0.98\n",
      "------------ Leaf value=-0.03\n"
     ]
    }
   ],
   "source": [
    "#打印树的方法\n",
    "def print_tree(node, prefix=''):\n",
    "    prefix += '-' * 4\n",
    "    print(prefix, node)\n",
    "    if isinstance(node, Leaf):\n",
    "        return\n",
    "    print_tree(node.gt_node, prefix)\n",
    "    print_tree(node.lt_node, prefix)\n",
    "\n",
    "\n",
    "print_tree(root)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#预测\n",
    "pred = np.empty(N)\n",
    "for i in range(N):\n",
    "    pred[i] = root(data[i])\n",
    "\n",
    "draw(pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "b'\\x80\\x03c__main__\\nNode\\nq\\x00)\\x81q\\x01}q\\x02(X\\x03\\x00\\x00\\x00colq\\x03K\\x01X\\x05\\x00\\x00\\x00valueq\\x04cnumpy.core.multiarray\\nscalar\\nq\\x05cnumpy\\ndtype\\nq\\x06X\\x02\\x00\\x00\\x00f8q\\x07\\x89\\x88\\x87q\\x08Rq\\t(K\\x03X\\x01\\x00\\x00\\x00<q\\nNNNJ\\xff\\xff\\xff\\xffJ\\xff\\xff\\xff\\xffK\\x00tq\\x0bbC\\x08\\xcc]K\\xc8\\x07=\\xd9?q\\x0c\\x86q\\rRq\\x0eX\\x07\\x00\\x00\\x00lt_nodeq\\x0fh\\x00)\\x81q\\x10}q\\x11(h\\x03K\\x01h\\x04h\\x05h\\tC\\x08\\xf6\\xb7\\x04\\xe0\\x9fR\\xc9?q\\x12\\x86q\\x13Rq\\x14h\\x0fc__main__\\nLeaf\\nq\\x15)\\x81q\\x16}q\\x17h\\x04h\\x05h\\tC\\x08\\xf8\\xf0\\xd57\\xd9\\xaf\\x9c\\xbfq\\x18\\x86q\\x19Rq\\x1asbX\\x07\\x00\\x00\\x00gt_nodeq\\x1bh\\x15)\\x81q\\x1c}q\\x1dh\\x04h\\x05h\\tC\\x08\\x94\\xbe#=\\x1fx\\xef?q\\x1e\\x86q\\x1fRq sbubh\\x1bh\\x00)\\x81q!}q\"(h\\x03K\\x01h\\x04h\\x05h\\tC\\x08\\xb3\\x97m\\xa7\\xad\\x91\\xe2?q#\\x86q$Rq%h\\x0fh\\x15)\\x81q&}q\\'h\\x04h\\x05h\\tC\\x08\\xfb\\xc9\\x18\\x1ff\\xb3\\xff?q(\\x86q)Rq*sbh\\x1bh\\x00)\\x81q+}q,(h\\x03K\\x01h\\x04h\\x05h\\tC\\x08\\xe5\\x0e\\x9b\\xc8\\xcc\\x85\\xe9?q-\\x86q.Rq/h\\x0fh\\x15)\\x81q0}q1h\\x04h\\x05h\\tC\\x08\\xa1}\\x10Yr\\r\\x08@q2\\x86q3Rq4sbh\\x1bh\\x15)\\x81q5}q6h\\x04h\\x05h\\tC\\x08z\\x9d\\x1e%\\xc0\\xca\\x0f@q7\\x86q8Rq9sbububub.'\n"
     ]
    }
   ],
   "source": [
    "import pickle\n",
    "\n",
    "#序列化树对象,导入后剪枝算法\n",
    "print(pickle.dumps(root))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
